package io.dy.custom_pool;

import java.util.ArrayDeque;
import java.util.Date;
import java.util.Deque;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : dmj
 * @date: 2024/11/27 3:52 下午
 * @description: 阻塞队列
 */
public class DyBlockQueue<T> {

    /**
     * 数据队列
     */
    private final Deque<T> queue = new ArrayDeque<>();

    /**
     * 主锁
     */
    private final Lock lock = new ReentrantLock();

    /**
     * 空队列等待
     */
    private final Condition emptyWaitSet = DyBlockQueue.this.lock.newCondition();

    /**
     * 队列已满等待
     */
    private final Condition fullWaitSet = DyBlockQueue.this.lock.newCondition();

    /**
     * 队列大小
     */
    private final int capacity;

    public DyBlockQueue(int capacity){
        this.capacity = capacity;
    }


    public T take(){
        System.out.println(Thread.currentThread().getName() + " 准备抢占锁资源..." + new Date());
        lock.lock();
        System.out.println(Thread.currentThread().getName() + " 准备抢占锁资源成功..." + new Date());
        try {
           while (queue.isEmpty()){
               try {
                   Thread.sleep(1000);
                   emptyWaitSet.await();
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
            T t = queue.removeFirst();
           fullWaitSet.signalAll();
           return t;
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        DyBlockQueue<String> queue = new DyBlockQueue<>(2);

        new Thread(()->{
            queue.take();
        }, "thread-01").start();
        new Thread(()->{
            queue.take();
        }, "thread-02").start();
    }
}
